﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearRegression;
using Python.Runtime;
using ScottPlot;

namespace 调平
{
    internal class Program
    {
        private static async Task Main()
        {
            // --------------------------------------------------
            // 1. 设置Python环境
            // --------------------------------------------------
            // !!! 非常重要 !!!
            // 指定Python安装目录下的pythonXX.dll文件路径。
            // 根据你的Python版本和安装位置进行调整。
            // 例如: @"C:\Python\Python39\python39.dll"
            // 或者如果你使用的是Anaconda/Miniconda: @"C:\Users\YourUser\miniconda3\python39.dll"
            // 确保使用正确的Python版本（32位或64位）与你的C#应用程序匹配。
            // 如果你的C#项目是Any CPU，它会以64位运行在64位系统上，所以需要64位Python DLL。
            string pythonDll = @"D:\Python3.8\python38.dll";

            // 检查DLL是否存在
            if (!File.Exists(pythonDll))
            {
                Console.WriteLine($"错误: Python DLL 文件不存在于 {pythonDll}");
                Console.WriteLine("请更新 'pythonDll' 变量为你的Python安装目录下的正确路径。");
                return;
            }

            Runtime.PythonDLL = pythonDll;

            // 初始化Python解释器
            PythonEngine.Initialize();

            // --------------------------------------------------
            // 2. 准备要传递给Python的传感器数据
            // --------------------------------------------------
            var topData = new Dictionary<string, double>
                {
                    {"In0_1", -1.1403}, {"In0_2", -0.49795}, {"In0_3", -0.48396}, {"Mid0", 0.723984},
                    {"In45_1", -4.14708}, {"In45_2", -1.12862}, {"In45_3", -0.15862}, {"Mid45", -1.05302},
                    {"In90_1", -3.32994}, {"In90_2", -1.24022}, {"In90_3", -5.72106}, {"Mid90", -1.57782},
                    {"In135_1", -0.15294}, {"In135_2", -0.69661}, {"In135_3", 0.057983}, {"Mid135", -0.07529},
                    {"In180_1", -5.03629}, {"In180_2", -2.33409}, {"In180_3", -0.28073}, {"Mid180", -0.47427},
                    {"In225_1", -2.05827}, {"In225_2", -0.39931}, {"In225_3", -0.02208}, {"Mid225", -3.7834},
                    {"In270_1", -1.46562}, {"In270_2", -3.82315}, {"In270_3", -2.86399}, {"Mid270", -0.45112},
                    {"In315_1", -0.37607}, {"In315_2", -3.29916}, {"In315_3", -0.30993}, {"Mid315", -0.07433}
                };

            var bottomData = new Dictionary<string, double>
                {
                    {"In0_1", 452.9827}, {"In0_2", 482.4379}, {"In0_3", 504.1031}, {"Mid0", 593.8483},
                    {"In45_1", 424.7843}, {"In45_2", 448.6953}, {"In45_3", 466.5681}, {"Mid45", 530.7994},
                    {"In90_1", 366.8405}, {"In90_2", 369.5793}, {"In90_3", 371.002}, {"Mid90", 369.9449},
                    {"In135_1", 310.1958}, {"In135_2", 290.2955}, {"In135_3", 274.0139}, {"Mid135", 212.0351},
                    {"In180_1", 280.4393}, {"In180_2", 255.1347}, {"In180_3", 232.6828}, {"Mid180", 142.3179},
                    {"In225_1", 307.87}, {"In225_2", 289.9182}, {"In225_3", 272.418}, {"Mid225", 210.4822},
                    {"In270_1", 368.3336}, {"In270_2", 366.567}, {"In270_3", 366.6739}, {"Mid270", 373.8856},
                    {"In315_1", 428.9884}, {"In315_2", 446.7372}, {"In315_3", 466.1387}, {"Mid315", 530.8607}
                };

            var adjustedData = new Dictionary<string, double>
                {
                    {"In0_1", 454.123}, {"In0_2", 482.9359}, {"In0_3", 504.5871}, {"Mid0", 593.1243},
                    {"In45_1", 428.9314}, {"In45_2", 449.8239}, {"In45_3", 466.7267}, {"Mid45", 531.8524},
                    {"In90_1", 370.1704}, {"In90_2", 370.8195}, {"In90_3", 376.723}, {"Mid90", 371.5228},
                    {"In135_1", 310.3487}, {"In135_2", 290.9921}, {"In135_3", 273.9559}, {"Mid135", 212.1104},
                    {"In180_1", 285.4756}, {"In180_2", 257.4688}, {"In180_3", 232.9635}, {"Mid180", 142.7922},
                    {"In225_1", 309.9282}, {"In225_2", 290.3175}, {"In225_3", 272.4401}, {"Mid225", 214.2656},
                    {"In270_1", 369.7992}, {"In270_2", 370.3902}, {"In270_3", 369.5378}, {"Mid270", 374.3367},
                    {"In315_1", 429.3644}, {"In315_2", 450.0364}, {"In315_3", 466.4486}, {"Mid315", 530.9351}
                };

            try
            {
                using (Py.GIL()) // 获取 Python 全局解释器锁
                {
                    try
                    {
                        // --------------------------------------------------
                        // 1. 将 C# 字典显式转换为 Python 字典
                        // --------------------------------------------------
                        var pyTopData = new PyDict();
                        foreach (var kvp in topData)
                        {
                            pyTopData.SetItem(kvp.Key.ToPython(), kvp.Value.ToPython());
                        }

                        var pyBottomData = new PyDict();
                        foreach (var kvp in bottomData)
                        {
                            pyBottomData.SetItem(kvp.Key.ToPython(), kvp.Value.ToPython());
                        }

                        var pyAdjustedData = new PyDict();
                        foreach (var kvp in adjustedData)
                        {
                            pyAdjustedData.SetItem(kvp.Key.ToPython(), kvp.Value.ToPython());
                        }

                        // --------------------------------------------------
                        // 2. 设置 Python 模块搜索路径并导入模块
                        // --------------------------------------------------
                        dynamic sys = Py.Import("sys");
                        string scriptPath = @"D:\MyProjects\GitProjects\webApi\调平";
                        sys.path.append(scriptPath);

                        Console.WriteLine("[调试] Python模块搜索路径:");
                        foreach (var path in sys.path)
                        {
                            Console.WriteLine(path.ToString());
                        }

                        Console.WriteLine("尝试导入 tp 模块...");
                        dynamic tp = Py.Import("tp");
                        Console.WriteLine("模块导入成功！");

                        // --------------------------------------------------
                        // 3. 准备图形保存路径
                        // --------------------------------------------------
                        var imageDir = Path.Combine(
                            AppDomain.CurrentDomain.BaseDirectory,
                            "testimages"
                        );
                        Directory.CreateDirectory(imageDir); // 确保目录存在
                        string plotSavePath = Path.Combine(imageDir, $"plane_fitting_plot_pythonnet_{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.png");

                        // --------------------------------------------------
                        // 4. 调用 Python 函数并处理结果
                        // --------------------------------------------------
                        Console.WriteLine("调用 Python 函数 process_sensor_data...");
                        dynamic pythonResults = tp.process_sensor_data(
                            pyTopData,
                            pyBottomData,
                            pyAdjustedData,
                            plotSavePath
                        );

                        // --------------------------------------------------
                        // 5. 解析并打印结果
                        // --------------------------------------------------
                        if (pythonResults.HasAttr("error"))
                        {
                            Console.WriteLine($"\nPython 脚本报告错误: {pythonResults.error.ToString()}");
                        }
                        else
                        {
                            Console.WriteLine("\n--- 平面拟合计算结果 ---");
                            Console.WriteLine($"Topchuck 平面: a={pythonResults["top_plane"]["a"]:.6f}, b={pythonResults["top_plane"]["b"]:.6f}, c={pythonResults["top_plane"]["c"]:.6f}, RMS误差={pythonResults["top_plane"]["rms_error"]:.6f}");
                            Console.WriteLine($"Bottomchuck 平面: a={pythonResults["bottom_plane"]["a"]:.6f}, b={pythonResults["bottom_plane"]["b"]:.6f}, c={pythonResults["bottom_plane"]["c"]:.6f}, RMS误差={pythonResults["bottom_plane"]["rms_error"]:.6f}");
                            Console.WriteLine($"Adjusted 平面: a={pythonResults["adjusted_plane"]["a"]:.6f}, b={pythonResults["adjusted_plane"]["b"]:.6f}, c={pythonResults["adjusted_plane"]["c"]:.6f}, RMS误差={pythonResults["adjusted_plane"]["rms_error"]:.6f}");

                            Console.WriteLine($"\n初始需要调整: rx={pythonResults["initial_adjustment_needed"]["rx_µrad"]:.2f} µrad, ry={pythonResults["initial_adjustment_needed"]["ry_µrad"]:.2f} µrad");
                            Console.WriteLine($"调整后残差: rx={pythonResults["residual_after_adjustment"]["rx_after_µrad"]:.2f} µrad, ry={pythonResults["residual_after_adjustment"]["ry_after_µrad"]:.2f} µrad");
                            Console.WriteLine($"\n改善百分比: rx={pythonResults["improvement_percentage"]["rx_improvement"]:.2f}%, ry={pythonResults["improvement_percentage"]["ry_improvement"]:.2f}%");

                            // 检查图形是否生成
                            if (File.Exists(plotSavePath))
                            {
                                Console.WriteLine($"\n图形已保存到: {plotSavePath}");
                            }
                            else
                            {
                                Console.WriteLine("\n警告: 图形文件未生成，请检查 Python 绘图代码");
                            }
                        }
                    }
                    catch (PythonException ex)
                    {
                        Console.WriteLine("\n!!! Python 运行时错误 !!!");
                        Console.WriteLine(ex.Message);

                        // 获取 Python 的完整错误堆栈
                        dynamic traceback = Py.Import("traceback");
                        Console.WriteLine(traceback.format_exc().ToString());
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("\n!!! C# 运行时错误 !!!");
                        Console.WriteLine(ex.Message);
                        Console.WriteLine(ex.StackTrace);
                    }
                    finally
                    {
                        PythonEngine.Shutdown();
                    }
                }
            }
            catch (PythonException pyEx)
            {
                Console.WriteLine($"\nPython运行时错误: {pyEx.Message}");
                Console.WriteLine(pyEx.StackTrace);
                Console.WriteLine("Python Traceback:\n" + pyEx.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"\n发生C#错误: {ex.Message}");
                Console.WriteLine(ex.StackTrace);
            }
            finally
            {
                // --------------------------------------------------
                // 5. 关闭Python解释器
                // --------------------------------------------------
                PythonEngine.Shutdown();
                Console.WriteLine("\nPython解释器已关闭。");
                Console.ReadLine();
            }
        }
    }
}